package com.qpf.mycms.component.swagger;

import cn.hutool.core.util.ObjectUtil;
import com.qpf.mycms.component.swagger.properties.SwaggerProperties;

import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.servers.Server;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@Configuration
@EnableConfigurationProperties(SwaggerProperties.class)
@ConditionalOnProperty(prefix = "mycms.swagger", name = "enable", havingValue = "true") // 开启条件
public class SwaggerConfiguration {
    private final SwaggerProperties swaggerProperties;
    @Autowired
    public SwaggerConfiguration(SwaggerProperties swaggerProperties) {
        this.swaggerProperties = swaggerProperties;
        System.out.println(swaggerProperties);
    }

    @Bean
    public OpenAPI openAPI(){
        Info info = new Info();
        //创建Api帮助文档的描述信息、联系人信息(contact)、授权许可信息(license)
        SwaggerProperties.Info infoValue = swaggerProperties.getInfo();
        if (!ObjectUtils.isEmpty(infoValue)) {
            info = new Info()
                    .title(infoValue.getTitle())      // Api接口文档标题（必填）
                    .description(infoValue.getDescription())     // Api接口文档描述
                    .version(infoValue.getVersion())                                  // Api接口版本
                    .termsOfService(infoValue.getTermsOfService())    // Api接口的服务条款地址
            ;
            // 联系人信息(contact)，构建API的联系人信息，用于描述API开发者的联系信息，包括名称、URL、邮箱等
            SwaggerProperties.Contact contactVal = infoValue.getContact();
            if (!ObjectUtil.isEmpty(contactVal)) {
                Contact contact = new Contact()
                        .name(contactVal.getName())  // 作者名称
                        .email(contactVal.getEmail()) // 作者邮箱
                        .url(contactVal.getUrl()) // 介绍作者的URL地址
                        .extensions(new HashMap<>());// 使用Map配置信息（如key为"name","email","url"）
                info.contact(contact); // 设置联系人信息
            }
            SwaggerProperties.License licenseVal = infoValue.getLicense();
            if (!ObjectUtil.isEmpty(licenseVal)) {
                License license = new License()
                        .name(licenseVal.getName())                         // 授权名称
                        .url(licenseVal.getUrl())    // 授权信息
                        .identifier(licenseVal.getIdentifier())                   // 标识授权许可
                        .extensions(new HashMap<>())
//                    .name("Apache 2.0")                         // 授权名称
//                    .url("https://www.apache.org/licenses/LICENSE-2.0.html")    // 授权信息
//                    .identifier("Apache-2.0")                   // 标识授权许可
//                    .extensions(new HashMap<String, Object>())
                        ;// 使用Map配置信息（如key为"name","url","identifier"）
                info.license(license);  //   授权名称
            }
        }
        List<Server> servers = new ArrayList<>(); //多服务
        if (!ObjectUtil.isEmpty(swaggerProperties.getServers())) {
            servers = swaggerProperties.getServers().stream().map(item-> new Server().url(item.getUrl()).description(item.getDesc())).collect(Collectors.toList());
        }

        // // 设置 spring security apikey accessToken 认证的请求头 X-Token: xxx.xxx.xxx
//        SecurityScheme securityScheme = new SecurityScheme()
//                .name("x-token")
//                .type(SecurityScheme.Type.APIKEY)
//                .description("APIKEY认证描述")
//                .in(SecurityScheme.In.HEADER);

        // 设置 spring security jwt accessToken 认证的请求头 Authorization: Bearer xxx.xxx.xxx
        SecurityScheme securityScheme1 = new SecurityScheme()
                .name("JWT认证")
                .scheme("bearer") //如果是Http类型，Scheme是必填
                .type(SecurityScheme.Type.HTTP)
                .description("认证描述")
                .in(SecurityScheme.In.HEADER)
                .bearerFormat("JWT");

        List<SecurityRequirement> securityRequirements = new ArrayList<>();

        SecurityRequirement securityRequirement = new SecurityRequirement();
        securityRequirement.addList("authScheme");

        securityRequirements.add(securityRequirement);

        // 返回信息
        return new OpenAPI()
                //.openapi("3.0.1")  // Open API 3.0.1(默认)
                .info(info)
                .servers(servers)
                .components(new Components().addSecuritySchemes("authScheme",securityScheme1)) //添加鉴权组件
                .security(securityRequirements) //全部添加鉴权小锁
                .externalDocs(new ExternalDocumentation()
                        .description("对外说明") //对外说明
                        .url("https://www.cnblogs.com/vic-tory/"));       // 配置Swagger3.0描述信息
    }
}
